package com.zc.controller;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.alibaba.ttl.threadpool.TtlExecutors;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.*;

@RestController
@RequestMapping("test")
public class TestTtlController {

    private static final ThreadLocal<Map<Object, Object>> threadLocal = new TransmittableThreadLocal(){
        @Override
        protected Object copy(Object parentValue) {
            return new LinkedHashMap((Map) parentValue);
        }

        @Override
        protected Object childValue(Object parentValue) {
            return new LinkedHashMap((Map) parentValue);
        }

        @Override
        protected Object initialValue() {
            Map map = new LinkedHashMap<>();
            Map inMap = new HashMap();
            inMap.put("a", "a");
            map.put("inMap", inMap);
            threadLocal.set(new LinkedHashMap<>());
            return map;
        }
    };
//    private Executor executor = new ThreadPoolExecutor(1, 1, 1000, TimeUnit.SECONDS, new LinkedBlockingQueue<>());
    private Executor executor = TtlExecutors.getTtlExecutor(new ThreadPoolExecutor(1, 1, 1000, TimeUnit.SECONDS, new LinkedBlockingQueue<>()));

    Integer i = 0;

    static {
        init();
    }

    @GetMapping("/ttl")
    public String testTtl() throws InterruptedException {
        Map<Object, Object> map = threadLocal.get();
        if (map == null) {
           init();
        }
        threadLocal.get().put(++i ,i);
        System.out.println("主线程set:" + i);
        executor.execute(() -> {
            try {
                Thread.sleep(2 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Map<Object, Object> objectObjectMap = threadLocal.get();
            Map inMap = (Map) objectObjectMap.get("inMap");
            inMap.put("b", "b");
            System.out.println("子线程get: " + threadLocal.get());
        });
        executor.execute(() -> {
            try {
                Thread.sleep(4 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            Map<Object, Object> objectObjectMap = threadLocal.get();
            Map inMap = (Map) objectObjectMap.get("inMap");
            inMap.put("c", "c");
            System.out.println("子线程get: " + threadLocal.get());
        });
        threadLocal.get().put(++i ,i);
        threadLocal.remove();
        return "success";
    }

    private static synchronized void init() {
        Map<Object, Object> map = threadLocal.get();
        System.out.println("初始化完成~~~");

    }
}
